import React, { useMemo, useEffect, useCallback } from 'react'
import { createForm, onFieldInit } from '@formily/core'
import { createSchemaField } from '@formily/react'
import {
  useT,
  createEvent,
  $showLoading,
  $hideLoading,
} from '@designable/event-system'
import {
  FormItem,
  Checkbox,
  Cascader,
  Editable,
  NumberPicker,
  Switch,
  Password,
  PreviewText,
  Radio,
  Reset,
  Select,
  Space,
  Submit,
  TimePicker,
  Transfer,
  TreeSelect,
  Upload,
  FormGrid,
  FormLayout,
  FormTab,
  FormCollapse,
  ArrayTable,
  ArrayCards,
  ArrayItems,
  Form as FormilyForm,
} from '@formily/antd'
import {
  ProTable,
  Dialog,
  Text,
  FormStep,
  CustomAgreementForm,
  Input,
  ColorPicker,
  UploadImage,
  LabelTitle,
  BraftEditor,
  MultiLanguageDialog,
  GoodsCategorySelect,
  GoodsExchangeRestrictions,
  FixedDuration,
  AfterPurchaseFixedDuration,
  Result,
  Button,
  Form,
  FormStepBase,
  DetailContainer,
  Descriptions,
  FormMonthDayPicker,
  FormBase,
  SingleCheckBox,
  CouponGoodsTableSelector,
  SuspendedBottom,
  DatePicker,
  QRCode,
  Timeline,
  OrderHeader,
  ButtonUploadExcel,
  SelectEquity,
  DetailHeader,
  DicProTable,
  ArrayTabs,
} from '../index'
import { Card, Slider, Rate } from 'antd'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const eventSystem = require('@designable/event-system') || {}

const schemaComponents = {
  FormStepBase,
  LabelTitle,
  FormStep,
  Form,
  Space,
  FormGrid,
  FormLayout,
  FormTab,
  FormCollapse,
  ArrayTable,
  ArrayCards,
  ArrayItems,
  FormItem,
  DatePicker,
  Checkbox,
  Cascader,
  Editable,
  Input,
  Text,
  NumberPicker,
  Switch,
  Password,
  PreviewText,
  Radio,
  Reset,
  Select,
  Submit,
  TimePicker,
  Transfer,
  TreeSelect,
  Upload,
  Card,
  Slider,
  Rate,
  ProTable,
  Dialog,
  Button,
  CustomAgreementForm,
  ColorPicker,
  UploadImage,
  BraftEditor,
  MultiLanguageDialog,
  GoodsCategorySelect,
  GoodsExchangeRestrictions,
  FixedDuration,
  AfterPurchaseFixedDuration,
  Result,
  DetailContainer,
  Descriptions,
  FormMonthDayPicker,
  FormBase,
  SingleCheckBox,
  CouponGoodsTableSelector,
  SuspendedBottom,
  QRCode,
  Timeline,
  OrderHeader,
  ButtonUploadExcel,
  SelectEquity,
  DetailHeader,
  DicProTable,
  ArrayTabs,
}

type PageSchema = {
  formProps?: any
  schema?: any
}

const isValidString = (value: any): value is string => {
  return typeof value === 'string' && value.length > 0
}

function translateSchemaFields(schema: any, options: any = {}, $t) {
  const {
    componentName = 'FormStep.StepPane', // 目标组件名
    fields = ['title', 'subTitle'], // 要翻译的字段
  } = options

  const processedSchema = JSON.parse(JSON.stringify(schema))

  function processObject(obj) {
    if (!obj || typeof obj !== 'object') return

    // 检查目标组件
    if (obj['x-component'] === componentName && obj['x-component-props']) {
      const props = obj['x-component-props']

      fields.forEach((field) => {
        if (isValidString(props[field])) {
          props[field] = $t(props[field] as string)
        }
      })
    }

    // 递归处理
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const value = obj[key]
        if (typeof value === 'object' && value !== null) {
          processObject(value)
        }
      }
    }
  }

  processObject(processedSchema)
  return processedSchema
}

const processFieldI18n = (field: any, $t: (key: string) => string) => {
  const fields = ['title', 'description'] as const
  fields.forEach((key) => {
    if (isValidString(field[key])) {
      field[key] = $t(field[key])
    }
  })
  const componentProps = field.componentProps || {}
  // 处理 componentProps 中的 placeholder
  if (componentProps.placeholder) {
    componentProps.placeholder = $t(componentProps.placeholder)
  } else {
    // 根据组件类型设置不同的默认 placeholder
    if (['Select', 'Cascader', 'TreeSelect'].includes(field.componentType)) {
      field.componentProps.placeholder = $t('请选择')
    } else if (
      ['Input', 'Input.TextArea', 'NumberPicker'].includes(field.componentType)
    ) {
      field.componentProps.placeholder = $t('请输入')
    }
  }

  const decoratorProps = field.decoratorProps
  if (decoratorProps) {
    decoratorProps.addonAfter &&
      (decoratorProps.addonAfter = $t(decoratorProps.addonAfter))
    decoratorProps.addonBefore &&
      (decoratorProps.addonBefore = $t(decoratorProps.addonBefore))
  }

  if (Array.isArray(field.dataSource)) {
    field.dataSource = field.dataSource.map((item: any) => {
      return {
        label: $t(item.label),
        value: item.value,
      }
    })
  }
}

export const SchemaApp: React.FC<{
  pageSchema: PageSchema
}> = ({ pageSchema }) => {
  const $t: (key: string) => string = useT()
  let { formProps = {}, schema }: any = pageSchema
  schema = translateSchemaFields(
    schema,
    { componentName: 'FormStep.StepPane', fields: ['title', 'subTitle'] },
    $t
  )
  const {
    useEffectExpression,
    form: formConfig,
    onFormReady,
    style,
    ...restFormProps
  } = formProps || {}

  const form = useMemo(
    () =>
      createForm({
        effects() {
          onFieldInit('*', (field) => {
            processFieldI18n(field, $t)
          })
        },
        ...formConfig, // 应用 formProps 中的 form 配置
      }),
    [$t, formConfig]
  )

  const executeUseEffectExpression = useCallback(
    async (expression: string) => {
      $showLoading()
      try {
        if (!expression) return
        const res = await createEvent(expression, {
          form,
          $t,
        })
        res && form.setValues(res)
      } catch (error) {
        console.error('执行 useEffectExpression 失败:', error)
      } finally {
        $hideLoading()
      }
    },
    [form, $t]
  )

  useEffect(() => {
    executeUseEffectExpression(useEffectExpression)
  }, [useEffectExpression])

  // 当 form 创建完成后，通过回调传递给父组件
  useEffect(() => {
    if (onFormReady && form) {
      onFormReady(form)
    }
  }, [form, onFormReady])

  const SchemaField = useMemo(() => {
    return createSchemaField({
      components: schemaComponents,
      scope: { $t, ...(eventSystem || {}) },
    })
  }, [$t])

  return schema ? (
    <div style={style}>
      <FormilyForm {...restFormProps} form={form}>
        <SchemaField schema={schema} />
      </FormilyForm>
    </div>
  ) : (
    <div>Loading...</div>
  )
}
